package org.example.concurrentUtils;

import java.util.HashMap;

/**
 * JDK7下 并发死链问题
 *
 * @author ZhengDp
 * @Date 2023/2/22 22:50
 */
public class HashMapDeadLock {
    public static void main(String[] args) {
        // 找到桶下标相同的key，只有下标相同，才会形成链表
        System.out.println("长度为16时，桶下标为1的key");
        for (int i = 0; i < 64; i++) {
            if (hash(i) % 16 == 1) {
                System.out.println(i);
            }
        }
        System.out.println("长度为32时，桶下表为1的key");
        for (int i = 0; i < 64; i++) {
            if (hash(i) % 32 == 1) {
                System.out.println(i);
            }
        }

        // 1,35,16,50 当大小为16时，他们在同一个桶里
        final HashMap<Integer, Integer> map = new HashMap<>();
        // 放12个元素
        map.put(2, null);
        map.put(3, null);
        map.put(4, null);
        map.put(5, null);
        map.put(6, null);
        map.put(7, null);
        map.put(8, null);
        map.put(9, null);
        map.put(10, null);
        map.put(16, null);
        map.put(35, null);
        map.put(1, null);

        // 模拟扩容场景，当元素个数超过3/4时，发生扩容
        // 两个线程都会触发扩容，这种情况下就会有死链发生。
        System.out.println("扩容前大小[main] : " + map.size());
        new Thread(() -> {
            // 放第13个元素，发生扩容
            map.put(50, null);
            System.out.println("扩容后大小[Thread-0]:" + map.size());
        }).start();
        new Thread(() -> {
            map.put(50, null);
            System.out.println("扩容后大小[Thread-1]:" + map.size());
        }).start();
    }


    final static int hash(Object k) {
        int h = 0;
        if (0 != h && k instanceof String) {
            return 0;
        }
        h ^= k.hashCode();
        h ^= (h >>> 20) ^ (h >>> 12);
        return h ^ (h >>> 7) ^ (h >>> 4);
    }

}